﻿using System;

using agsXMPP;

using agsXMPP.protocol.client;

using VSTalk.Engine.Core.Context;
using VSTalk.Engine.Core.EntitySession;
using VSTalk.Engine.Core.XmppUtils;
using VSTalk.Model;

namespace VSTalk.Engine.Core.Feed
{
    public static class AddressPatterns
    {
        public static Predicate<IMessage> From(Interlocutor interlocutor)
        {
            return message =>
            {
                var client = AppServices.Get<IModelContext>().GetClientByContact(interlocutor);
                if (client == null) return false;
                if (message.XmppMessage.From == null) return false;
                return message.ClientId == client.Id &&
                       string.Equals(message.XmppMessage.From.Bare,
                       XmppIdConverter.Jid(interlocutor).Bare);
            };
        }

        public static Predicate<IMessage> To(Interlocutor interlocutor)
        {
            return message =>
            {
                var client = AppServices.Get<IModelContext>().GetClientByContact(interlocutor);
                if (client == null) return false;
                if (message.XmppMessage.To == null) return false;
                return message.ClientId == client.Id &&
                       string.Equals(message.XmppMessage.To.Bare,
                       XmppIdConverter.Jid(interlocutor).Bare);
            };
        }

        public static Predicate<IMessage> From(Room room)
        {
            return message =>
            {
                var client = AppServices.Get<IModelContext>().GetClientByRoom(room);
                if (client == null) return false;
                if (message.XmppMessage.From == null) return false;
                return message.ClientId == client.Id &&
                       string.Equals(message.XmppMessage.From.Bare,
                       XmppIdConverter.Jid(room).Bare);
            };
        }

        public static Predicate<IMessage> To(Room room)
        {
            return message =>
            {
                var client = AppServices.Get<IModelContext>().GetClientByRoom(room);
                if (client == null) return false;
                if (message.XmppMessage.To == null) return false;
                return message.ClientId == client.Id &&
                       string.Equals(message.XmppMessage.To.Bare,
                       XmppIdConverter.Jid(room).Bare);
            };
        }

        public static Predicate<IMessage> With(Guid clientId, Jid jid)
        {
            return arg => arg.ClientId == clientId &&
                          ((arg.XmppMessage.From != null && string.Equals(jid.Bare, arg.XmppMessage.From.Bare)) ||
                           (arg.XmppMessage.To != null && string.Equals(jid.Bare, arg.XmppMessage.To.Bare)));
        }

        public static Predicate<IQ> To(Client _client, Interlocutor interlocutor)
        {
            return iq => (iq.From != null && iq.To != null) && (string.Equals(iq.To.Bare.ToLower(), XmppIdConverter.Jid(_client).Bare.ToLower()) && 
                string.Equals(iq.From.Bare.ToLower(), XmppIdConverter.Jid(interlocutor).Bare.ToLower()));
        }

    }
}